﻿
using System;
using System.Diagnostics;
using System.Reflection;
using System.Xaml;
using System.Xaml.Schema;

using alib;
using alib.Debugging;

namespace agree.schema.xaml
{
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/// 
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	public sealed class xaml_attached : XamlMember
	{
		xaml_attached(String name, xaml_schema xsch, MethodInfo mi_get, MethodInfo mi_set, Type t_value)
			: base(name, mi_get, mi_set, xsch)
		{
			this.xt_value = xsch.GetXamlType(t_value);
		}
		xaml_attached(schema_prop_attachable spa, Func<Object, Object> getter, Action<Object, Object> setter)
			: this(spa.Name, spa.sch.xsch, getter.Method, setter.Method, spa.t_value)
		{
		}
		xaml_attached(xaml_attached.ivk ivk)
			: this(ivk.spa, ivk.GetValue, ivk.SetValue)
		{
			this.invoker = ivk;
		}
		public xaml_attached(schema_prop_attachable spa)
			: this(new xaml_attached.ivk(spa))
		{
			this.spa = spa;
		}

		readonly XamlType xt_value;
		readonly schema_prop_attachable spa;
		readonly ivk invoker;

		protected override XamlType LookupType() { return xt_value; }

		protected override ICustomAttributeProvider LookupCustomAttributeProvider() { return spa; }

		protected override XamlMemberInvoker LookupInvoker() { return invoker; }

		protected override bool LookupIsReadPublic() { return true; }

		protected override bool LookupIsWritePublic() { return true; }

		protected override bool LookupIsReadOnly() { return false; }

		protected override bool LookupIsWriteOnly() { return false; }

		sealed class ivk : XamlMemberInvoker
		{
			public ivk(schema_prop_attachable spa)
			{
				this.spa = spa;
			}
			public readonly schema_prop_attachable spa;

			public sealed override Object GetValue(Object obj)
			{
				return spa.GetValue(obj, BindingFlags.Default, null, null, null);
			}

			public sealed override void SetValue(Object obj, Object value)
			{
				spa.SetValue(obj, value, BindingFlags.Default, null, null, null);
			}
		};
	};
}